package de.szut.xml;

import android.util.Log;
import de.szut.entity.*;
import de.szut.util.ModifierType;
import de.szut.util.ModifierValueType;
import org.xmlpull.v1.XmlPullParser;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * TODO
 * Created by dzebcuks on 19.08.13.
 */
public class AbilityXmlParser extends XmlParser {

    private static final String ABILITY_TREE = "ability-tree";

    private static final String BASE_ABILITY = "base-ability";

    private static final String UPGRADE_ABILITY = "ability-upgrade";

    private static final String MODIFIER = "modifier";

    private static final String MODIFIER_VALUE = "value";

    private static final String DATA = "data";

    private AbilityTree abilityTree = null;

    private Ability ability = null;

    private Ability dependentAbility = null;

    private int ranknumber = 0;


    /**
     * Parses the modifier tag to a ModifierValue object
     *
     * @param parser
     * @return
     */
    private ModifierValue readModifierValue(XmlPullParser parser) {
        ModifierValue modValue = new ModifierValue();
        modValue.setValue(Integer.valueOf(parser.getAttributeValue(null, "value")));
        modValue.setType(ModifierValueType.valueOf(parser.getAttributeValue(null, "type")));
        return modValue;
    }

    /**
     * Parses the upgrade-ability tag to a AbilityUpgrade object
     *
     * @param parser
     * @param dependentAbility
     * @param ranknumber
     * @return
     */
    private AbilityUpgrade readUpgradeAbility(XmlPullParser parser, Ability dependentAbility,
                                              int ranknumber) {
        AbilityUpgrade abilityUpgrade = new AbilityUpgrade();
        if (parser.getAttributeValue(null, "image") != null) {
            abilityUpgrade.setImage(parser.getAttributeValue(null, "image"));
        }
        abilityUpgrade.setPoints(Integer.valueOf(parser.getAttributeValue(null, "points")));
        abilityUpgrade.setRankNumber(ranknumber);
        abilityUpgrade.setDependentAbility(dependentAbility);
        return abilityUpgrade;
    }

    /**
     * Parses the modifier tag to a Modifier object
     *
     * @param parser
     * @return
     */
    private Modifier readModifier(XmlPullParser parser) {
        Modifier modifier = new Modifier();
        modifier.setConnectedModifier(null); // TODO
        modifier.setType(ModifierType.valueOf(parser.getAttributeValue(null, "type")));
        return modifier;
    }

    /**
     * Parses the ability tag to a Ability object
     *
     * @param parser
     * @param abilityTree
     * @return
     */
    private BaseAbility readAbility(XmlPullParser parser, AbilityTree abilityTree) {
        BaseAbility ability = new BaseAbility();
        ability.setName(parser.getAttributeValue(null, "name"));
        ability.setDescription(parser.getAttributeValue(null, "description"));
        ability.setImage(parser.getAttributeValue(null, "image"));
        ability.setPoints(Integer.valueOf(parser.getAttributeValue(null, "points")));
        ability.setAbilityTree(abilityTree);
        abilityTree.getAbilities().add(ability);
        return ability;
    }

    @Override
    protected String getRequiredTag() {
        return AbilityXmlParser.DATA;
    }

    @Override
    protected List<String> getNecessaryTags() {
        return new ArrayList<String>(Arrays.asList(AbilityXmlParser.ABILITY_TREE,
                AbilityXmlParser.BASE_ABILITY, AbilityXmlParser.MODIFIER,
                AbilityXmlParser.MODIFIER_VALUE, AbilityXmlParser.UPGRADE_ABILITY));
    }

    @Override
    protected void handleTag(List<Object> objects, XmlPullParser parser, String tagName) {
        if (tagName.equals(AbilityXmlParser.ABILITY_TREE)) {
            abilityTree = new AbilityTree();
            abilityTree.setName(parser.getAttributeValue(null, "name"));
        } else if (tagName.equals(AbilityXmlParser.BASE_ABILITY)) {
            ability = this.readAbility(parser, abilityTree);
            dependentAbility = ability;
            ranknumber = 0;
        } else if (tagName.equals(AbilityXmlParser.MODIFIER)) {
            if (ability != null) {
                ability.setModifier(this.readModifier(parser));
            } else {
                Log.e("FATAL_XML_ERROR", "MODIFIER IS NOT INSIDE ABILITY!");
            }
        } else if (tagName.equals(AbilityXmlParser.UPGRADE_ABILITY)) {
            if (dependentAbility != null) {
                ranknumber++;
                ability = this.readUpgradeAbility(parser, dependentAbility, ranknumber);
                dependentAbility = ability;
            } else {
                Log.e("FATAL_XML_ERROR", "UPGRADE ABILITY IS NOT INSIDE ABILITY");
            }
        } else if (tagName.equals(AbilityXmlParser.MODIFIER_VALUE)) {
            if (ability != null) {
                ability.getModifier().setModifierValue(this.readModifierValue(parser));
                objects.add(ability);
            } else {
                Log.e("FATAL_XML_ERROR", "MODIFIER VALUE IS NOT ALLOWED TO BE USED OUTSIDE OF" +
                        " ABILITY TAG");
            }
        }
    }
}
